using System.Security.Cryptography;
using System.Text;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.RateLimiting;
using Microsoft.Extensions.Caching.Memory;

namespace HamsterDocs.Hosting.Services;

public class CaptchaService
{
    [HttpGet("captcha")]
    [AllowAnonymous]
    [EnableRateLimiting("auth")]
    public ActionResult<CaptchaResponse> GetCaptcha(
        [FromServices] IMemoryCache cache,
        [FromServices] IConfiguration configuration)
    {
        var expireSection = configuration.GetSection("Captcha");
        var expireSeconds = int.TryParse(expireSection["ExpireSeconds"], out var es) ? es : 120;

        var a = RandomNumberGenerator.GetInt32(1, 10);
        var b = RandomNumberGenerator.GetInt32(1, 10);
        var op = RandomNumberGenerator.GetInt32(0, 2) == 0 ? "+" : "-";
        int answer;
        string expr;
        if (op == "+")
        {
            answer = a + b;
            expr = $"{a} + {b} = ?";
        }
        else
        {
            if (a < b)
            {
                var tmp = a;
                a = b;
                b = tmp;
            }
            answer = a - b;
            expr = $"{a} - {b} = ?";
        }

        var svg = "<svg xmlns='http://www.w3.org/2000/svg' width='140' height='50'>" +
                  "<rect width='100%' height='100%' fill='#f5f5f5'/>" +
                  "<text x='50%' y='50%' dominant-baseline='middle' text-anchor='middle' font-size='24' fill='#333'>" +
                  expr +
                  "</text>" +
                  "</svg>";

        var base64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(svg));
        var dataUri = "data:image/svg+xml;base64," + base64;

        var captchaId = Guid.NewGuid().ToString("N");
        var cacheKey = "captcha:" + captchaId;
        cache.Set(cacheKey, answer, TimeSpan.FromSeconds(expireSeconds));

        return new OkObjectResult(new CaptchaResponse(captchaId, dataUri, expireSeconds));
    }

    public record CaptchaResponse(string CaptchaId, string ImageBase64, int ExpireSeconds);
}